/*
 * ConfigFile.java
 *
 * Created on May 19, 2007, 3:36 AM
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.system;

import java.net.URL;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 *
 * @author Main
 */
public class ConfigFile {
    String configfile = null;
    URL configfileURL;

    /** Creates a new instance of ConfigFile */
    public ConfigFile(String configfilename) throws IllegalArgumentException {
        try {
            this.configfileURL = new URL(configfilename);
        } catch (java.net.MalformedURLException me) {
            throw new IllegalArgumentException(me.getMessage());
        }
        configfile = getFile(configfileURL);
    }
    
    public ConfigFile(URL configfile) {
        this.configfileURL = configfile;
        this.configfile = getFile(configfileURL);
    }

    void removeConfig(String name) throws Exception {
        if (configfile==null) throw new Exception("Can't remove entry from configuration file. It is not loaded.");
        // look for config of the same name and delete it.
        if (configfile.indexOf("<" + name + ">")!=-1) {
            int start = configfile.indexOf("<" + name + ">");
            int end = configfile.indexOf("</" + name + ">") + name.length()+3;
            configfile.replaceAll("<" + name + ">.*</" + name + ">","");
            if (end>configfile.length()-1) end = configfile.length()-1;
            configfile = configfile.substring(0, start) + configfile.substring(end);

            // Writing to configfile. Can't write on a URL connection.
            BufferedWriter out = new BufferedWriter(new FileWriter(configfileURL.getFile()));
            out.write(configfile);
            out.close();
        }
    }
    
    private String getFile(URL file) {
        BufferedReader input = null;
        StringBuilder contents = new StringBuilder();
        try {
            input = new BufferedReader(new InputStreamReader(file.openStream()));
            String line = null; //not declared within while loop
            while (( line = input.readLine()) != null){
                contents.append(line).append(System.getProperty("line.separator"));
            }
        } catch (FileNotFoundException ex) {
            System.out.println("File not found: " + file.getPath() + " creating file.");
            return "";
        } catch (IOException ex){
            ex.printStackTrace();
            return null;
        } finally {
            try {
                if (input!= null)
                    input.close();
            } catch (IOException ex) {
                ex.printStackTrace();
                return null;
            }
        }
        
        // get info section if exists and replace variables with values
        return contents.toString();
    }
    
    public String[] get(String property) {
        if (configfile==null) return null;
        property = property.toLowerCase();
        String properties = configfile.replaceAll("<[^<^>]*>", "");
        List<String> found = new ArrayList<String>();
        StringTokenizer configTokenizer = new StringTokenizer(properties, ";");
        while (configTokenizer.hasMoreTokens()) {
            String token = configTokenizer.nextToken();
            if (token.indexOf('=')!=-1) {
                if (token.substring(0,token.indexOf('=')).trim().toLowerCase().equals(property)) {
                    found.add(token.substring(token.indexOf('=')+1));
                }
            }
        }

        String[] values = new String[found.size()];
        for (int i=0; i<found.size(); i++)
            values[i] = found.get(i);
        return values;
    }
    
    public void addConfig(Config config) throws IllegalArgumentException {
        if (configfile==null) throw new IllegalArgumentException("Can't add to configuration file. it is not loaded.");
        // look for old config of the same name and delete it.
        String name = config.getName();
        if (configfile.indexOf("<" + name + ">")!=-1) {
            int start = configfile.indexOf(System.getProperty("line.separator")+"<" + name + ">");
            if (start==-1) start = configfile.indexOf("<" + name + ">");
            int end = configfile.indexOf("</" + name + ">") + name.length()+3;
            configfile.replaceAll("<" + name + ">.*</" + name + ">", "");
            if (end>configfile.length()-1) end = configfile.length()-1;
            configfile = configfile.substring(0, start) + configfile.substring(end);
        }

        configfile += config.toString();
        
        // Writing to configfile. Can't write on a URL connection.
        try {
            BufferedWriter out = new BufferedWriter(new FileWriter(configfileURL.getFile()));
            out.write(configfile);
            out.close();
        } catch (IOException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    public String getFileName() {
        return this.configfileURL.getFile();
    }

    public boolean hasProperty(String property) {
        //should be more effecient... also get.
        String[] prop = get(property);
        return (prop!=null && prop.length!=0);
    }
}
